Configure multi-architecture Docker builds (amd64/arm64)#50
Configure multi-architecture Docker builds (amd64/arm64)#50raniellyferreira wants to merge 6 commits intomicrosoft:mainfrom
Conversation
Co-authored-by: raniellyferreira <4237908+raniellyferreira@users.noreply.github.com>
Co-authored-by: raniellyferreira <4237908+raniellyferreira@users.noreply.github.com>
Co-authored-by: raniellyferreira <4237908+raniellyferreira@users.noreply.github.com>
Co-authored-by: raniellyferreira <4237908+raniellyferreira@users.noreply.github.com>
…rch-build Configure multi-architecture Docker builds (amd64/arm64)
|
@microsoft-github-policy-service agree |
There was a problem hiding this comment.
Pull request overview
This PR migrates the Docker image build process from dotnet publish to Docker Buildx with multi-architecture support for AMD64 and ARM64 platforms. The change enables the application to run natively on Apple Silicon and AWS Graviton processors.
Changes:
- Added multi-stage Dockerfiles for both
Microsoft.McpGateway.ServiceandMicrosoft.McpGateway.Toolsusing .NET SDK 8.0 for build and ASP.NET 8.0 runtime for deployment - Updated GitHub Actions workflow to use Docker Buildx with QEMU for cross-platform builds targeting
linux/amd64andlinux/arm64 - Removed .NET SDK setup and
dotnet publishcommands from the CI workflow in favor of Docker-based builds
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| dotnet/Microsoft.McpGateway.Service/Dockerfile | New multi-stage Dockerfile for the main gateway service with build and runtime stages |
| dotnet/Microsoft.McpGateway.Tools/Dockerfile | New multi-stage Dockerfile for the tools gateway with build and runtime stages |
| .github/workflows/image.yml | Updated to use Docker Buildx with multi-architecture support, replacing dotnet publish approach |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| # Build and publish the application | ||
| WORKDIR /src/dotnet/Microsoft.McpGateway.Service/src | ||
| RUN dotnet publish Microsoft.McpGateway.Service.csproj -c Release -o /app/publish --no-restore |
There was a problem hiding this comment.
The project file specifies <Platforms>x64</Platforms>, which may conflict with ARM64 builds. While dotnet publish without an explicit runtime identifier can auto-detect the target platform in Docker, this constraint might cause build issues or prevent proper ARM64 compilation. Consider either removing this constraint or adding explicit runtime identifier arguments to the publish command (e.g., --runtime linux-arm64 for ARM64 builds). Alternatively, you could verify that the multi-arch build actually produces native ARM64 binaries rather than running x64 binaries through emulation.
|
|
||
| # Build and publish the application | ||
| WORKDIR /src/dotnet/Microsoft.McpGateway.Tools/src | ||
| RUN dotnet publish Microsoft.McpGateway.Tools.csproj -c Release -o /app/publish --no-restore |
There was a problem hiding this comment.
The project file specifies <Platforms>x64</Platforms>, which may conflict with ARM64 builds. While dotnet publish without an explicit runtime identifier can auto-detect the target platform in Docker, this constraint might cause build issues or prevent proper ARM64 compilation. Consider either removing this constraint or adding explicit runtime identifier arguments to the publish command (e.g., --runtime linux-arm64 for ARM64 builds). Alternatively, you could verify that the multi-arch build actually produces native ARM64 binaries rather than running x64 binaries through emulation.
| - name: Build and push mcp-gateway multi-arch image | ||
| uses: docker/build-push-action@v5 | ||
| with: | ||
| dotnet-version: '8.x' | ||
|
|
||
| - name: Restore dependencies | ||
| run: dotnet restore dotnet/Microsoft.McpGateway.sln --runtime linux-x64 | ||
|
|
||
| - name: Publish and push the mcp-gateway container image | ||
| run: dotnet publish dotnet/Microsoft.McpGateway.Service/src/Microsoft.McpGateway.Service.csproj --configuration Release --no-restore /p:PublishProfile=github.pubxml /p:ContainerRepository=${{ github.repository_owner }}/mcp-gateway | ||
|
|
||
| - name: Publish and push the tool-gateway container image | ||
| run: dotnet publish dotnet/Microsoft.McpGateway.Tools/src/Microsoft.McpGateway.Tools.csproj --configuration Release --no-restore /p:PublishProfile=github.pubxml /p:ContainerRepository=${{ github.repository_owner }}/tool-gateway | ||
| context: . | ||
| file: ./dotnet/Microsoft.McpGateway.Service/Dockerfile | ||
| platforms: linux/amd64,linux/arm64 | ||
| push: true | ||
| tags: ghcr.io/${{ github.repository_owner }}/mcp-gateway:latest |
There was a problem hiding this comment.
The build action doesn't configure Docker layer caching, which can significantly improve build times, especially for multi-architecture builds. Consider adding cache-from and cache-to parameters to leverage GitHub Actions cache. For example:
cache-from: type=gha
cache-to: type=gha,mode=max
This will cache Docker layers between builds and speed up subsequent builds.
| - name: Build and push tool-gateway multi-arch image | ||
| uses: docker/build-push-action@v5 | ||
| with: | ||
| context: . | ||
| file: ./dotnet/Microsoft.McpGateway.Tools/Dockerfile | ||
| platforms: linux/amd64,linux/arm64 | ||
| push: true | ||
| tags: ghcr.io/${{ github.repository_owner }}/tool-gateway:latest |
There was a problem hiding this comment.
The build action doesn't configure Docker layer caching, which can significantly improve build times, especially for multi-architecture builds. Consider adding cache-from and cache-to parameters to leverage GitHub Actions cache. For example:
cache-from: type=gha
cache-to: type=gha,mode=max
This will cache Docker layers between builds and speed up subsequent builds.
| file: ./dotnet/Microsoft.McpGateway.Service/Dockerfile | ||
| platforms: linux/amd64,linux/arm64 | ||
| push: true | ||
| tags: ghcr.io/${{ github.repository_owner }}/mcp-gateway:latest |
There was a problem hiding this comment.
The Docker image is only tagged with latest, which makes it difficult to track versions and roll back if needed. Consider adding versioning tags based on git SHA, tag, or semantic version. For example, you could add tags like ghcr.io/${{ github.repository_owner }}/mcp-gateway:${{ github.sha }} or use docker/metadata-action to automatically generate appropriate tags.
| file: ./dotnet/Microsoft.McpGateway.Tools/Dockerfile | ||
| platforms: linux/amd64,linux/arm64 | ||
| push: true | ||
| tags: ghcr.io/${{ github.repository_owner }}/tool-gateway:latest |
There was a problem hiding this comment.
The Docker image is only tagged with latest, which makes it difficult to track versions and roll back if needed. Consider adding versioning tags based on git SHA, tag, or semantic version. For example, you could add tags like ghcr.io/${{ github.repository_owner }}/tool-gateway:${{ github.sha }} or use docker/metadata-action to automatically generate appropriate tags.
| FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime | ||
| WORKDIR /app |
There was a problem hiding this comment.
The Docker container is running as root user, which poses a security risk. The sample Dockerfiles in this repository (e.g., sample-servers/mcp-example/Dockerfile:4-24) create and switch to a non-root user. Consider adding a similar security measure by creating a non-root user and switching to it before the ENTRYPOINT.
| FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime | ||
| WORKDIR /app |
There was a problem hiding this comment.
The Docker container is running as root user, which poses a security risk. The sample Dockerfiles in this repository (e.g., sample-servers/mcp-example/Dockerfile:4-24) create and switch to a non-root user. Consider adding a similar security measure by creating a non-root user and switching to it before the ENTRYPOINT.
This PR adds multi-architecture support (amd64/arm64) to the Docker image builds, replacing the previous
dotnet publishapproach with Docker Buildx.Changes
Dockerfiles
Microsoft.McpGateway.ServiceandMicrosoft.McpGateway.ToolsGitHub Actions Workflow
dotnet publishwithdocker/build-push-action@v5linux/amd64,linux/arm64Benefits
✅ Multi-Architecture Support: Works on AMD64 and ARM64 (Apple Silicon, AWS Graviton)
✅ Optimized Layer Caching: Multi-stage builds leverage Docker cache
✅ Smaller Images: Runtime stage uses only ASP.NET runtime
✅ Automatic Manifest List: Docker automatically creates manifest lists
Testing
Both images have been built and validated locally:
mcp-gateway- multi-stage build completes successfullytool-gateway- multi-stage build completes successfullyUsage
Validation Results
Tested on: raniellyferreira#1